<html>
<head><meta charset="utf-8"><title>Stabilizing the other volatile ops? · t-libs · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/index.html">t-libs</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html">Stabilizing the other volatile ops?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="232520929"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232520929" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232520929">(Mar 31 2021 at 01:02)</a>:</h4>
<p>volatile load and store are stable, but the other volatile intrinsics are not. Namely: volatile_set_memory, volatile_copy_memory, unaligned_volatile_load, unaligned_volatile_store, volatile_copy_nonoverlapping_memory, </p>
<p>There are these slightly older issues about some of these: <a href="https://github.com/rust-lang/rust/issues/76892">https://github.com/rust-lang/rust/issues/76892</a>, <a href="https://github.com/rust-lang/rust/issues/58041">https://github.com/rust-lang/rust/issues/58041</a>, but neither issue seems to have had a comment from a T-libs member.</p>
<p>What would the T-libs concerns be for having any/all of these become stable? Do we just need some stabilization PRs or do people think that we'd need some sort of bigger effort?</p>



<a name="232520997"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232520997" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232520997">(Mar 31 2021 at 01:04)</a>:</h4>
<p>My only potential concern would be having a robust enough idea of what specifically they guarantee - Ralf may have ideas there?</p>



<a name="232563413"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232563413" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232563413">(Mar 31 2021 at 09:50)</a>:</h4>
<p>For volatile load/store we can get away with "it does what C does". But these other volatile ops don't really have an equivalent in C. I would prefer if we went with something better defined such as <a href="https://reviews.llvm.org/D27133">https://reviews.llvm.org/D27133</a> which is what you usually want in these cases.</p>



<a name="232606836"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232606836" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232606836">(Mar 31 2021 at 15:02)</a>:</h4>
<p>Well, volatile unaligned load and volatile unaligned store are perfectly clear, i think we can agree. I don't think they're common but I do think they're necessary to have available if that's thay you've gotta do.</p>



<a name="232607771"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232607771" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232607771">(Mar 31 2021 at 15:08)</a>:</h4>
<p>As to the other three, memory set, memory copy, and memory copy-nonoverlapping are all three obvious in what they do. They work like the non-volatile version but the compiler can't omit/add/split/merge the operations with other operations.</p>



<a name="232608498"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232608498" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232608498">(Mar 31 2021 at 15:12)</a>:</h4>
<p>I'm not sure what atomics would have to do with it <span class="user-mention" data-user-id="143274">@Amanieu</span></p>



<a name="232608559"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232608559" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232608559">(Mar 31 2021 at 15:12)</a>:</h4>
<p>Particularly: I want to use this on a device that doesn't have atomics in the first place</p>



<a name="232631350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232631350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232631350">(Mar 31 2021 at 17:24)</a>:</h4>
<p>Note that we already expose <code>Atomic*::load/store</code> on devices that don't support atomics.</p>



<a name="232632007"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232632007" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232632007">(Mar 31 2021 at 17:28)</a>:</h4>
<p>The LLVM docs on volatile memcpy explicitly say:</p>
<blockquote>
<p>If the isvolatile parameter is true, the llvm.memcpy call is a volatile operation. The detailed access behavior is not very cleanly specified and it is unwise to depend on it.</p>
</blockquote>



<a name="232639189"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232639189" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232639189">(Mar 31 2021 at 18:14)</a>:</h4>
<p>Sure, atomics are available, but they can be elided.</p>



<a name="232639289"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232639289" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232639289">(Mar 31 2021 at 18:14)</a>:</h4>
<p>What I want to have a bulk copy that can't be elided. I also don't care about the detailed access for these bulk operations. I just need, for example, "copy all of this 96k from ROM into VRAM as quick as you can go"</p>



<a name="232639396"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232639396" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232639396">(Mar 31 2021 at 18:15)</a>:</h4>
<p>And it doesn't have to be atomic at all, and it's clearly not single-instruction-sized accesses, it just needs to happen</p>



<a name="232639713"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232639713" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232639713">(Mar 31 2021 at 18:17)</a>:</h4>
<p>If you did need detailed access (eg, "only use u8 access for this part of memory"), then you could write an explicit loop using the correct data type</p>



<a name="232677432"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232677432" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232677432">(Mar 31 2021 at 22:47)</a>:</h4>
<blockquote>
<p>What I want to have a bulk copy that can't be elided. I also don't care about the detailed access for these bulk operations. I just need, for example, "copy all of this 96k from ROM into VRAM as quick as you can go"</p>
</blockquote>
<p>But the width of individual accesses could matter for some use-cases. Must a <code>memcpy_volatile(*const [u8], *mut [u8], usize)</code> compile to a bunch of 1-byte writes or is the compiler allowed to turn this into word-sized accesses?</p>



<a name="232690274"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232690274" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232690274">(Apr 01 2021 at 01:20)</a>:</h4>
<p>That's what we were just saying. LLVM documents say:</p>
<blockquote>
<p>The detailed access behavior is not very cleanly specified and it is unwise to depend on it.</p>
</blockquote>
<p>So, it does a copy, and precisely the access pattern of that copy basically isn't specified.</p>
<p>As I said above, if you need a precise access pattern to happen you'd have to write the loop yourself. If you don't need a precise access pattern you can just call the bulk operation.</p>



<a name="232691369"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232691369" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232691369">(Apr 01 2021 at 01:37)</a>:</h4>
<p>But stabilizing something that's not cleanly specified seems... unwise? At least we'd need a specification that says what is guaranteed to remain when llvm cleans up their mess.</p>



<a name="232691916"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232691916" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232691916">(Apr 01 2021 at 01:46)</a>:</h4>
<p>The point is that you deliberately <em>don't</em> want to specify the details. You would use the intrinsic when you <em>want</em> a bulk operation to simply happen without worrying about the details, and let LLVM do the best memcopy it can manage on the device.</p>



<a name="232693420"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232693420" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232693420">(Apr 01 2021 at 02:07)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> What exactly is your use case for a volatile memcpy?</p>



<a name="232695755"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232695755" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232695755">(Apr 01 2021 at 02:43)</a>:</h4>
<p>I already said: bulk copying ROM into VRAM</p>



<a name="232698794"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232698794" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232698794">(Apr 01 2021 at 03:33)</a>:</h4>
<p>I would have expected a normal <code>memcpy</code> to be sufficient for this.</p>



<a name="232698917"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232698917" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232698917">(Apr 01 2021 at 03:35)</a>:</h4>
<p>The VRAM that you are copying to is "externally visible" from the point of view of the compiler: since you conjured a pointer out of thin air it has to assume that some other code (e.g. the GPU) also has access to this memory so it cannot elide the <code>memcpy</code>.</p>



<a name="232699073"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232699073" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232699073">(Apr 01 2021 at 03:37)</a>:</h4>
<p>ROM and VRAM both behave like normal memory. Volatile mainly useful for things that <em>don't</em> act like memory. For example a hardware register that must be accessed with 32-bit loads/stores: you don't want the compiler to combine 2 operations into a 64-bit load/store or to split the operation into individual bytes.</p>



<a name="232701524"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232701524" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232701524">(Apr 01 2021 at 04:15)</a>:</h4>
<p>Yes I'm aware of the MMIO usage of volatile to control a device.</p>



<a name="232701594"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232701594" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232701594">(Apr 01 2021 at 04:16)</a>:</h4>
<p>However, I'm also aware of access elision, which is what I don't want to ever have happen.</p>



<a name="232701662"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232701662" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232701662">(Apr 01 2021 at 04:17)</a>:</h4>
<p>Now because this is an intrinsic I am literally unable to just write this myself, or I would do that and not ask the standard library to do it for me.</p>



<a name="232701846"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232701846" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232701846">(Apr 01 2021 at 04:20)</a>:</h4>
<p>You can just use <code>copy_nonoverlapping</code> for this: the compiler can't elide the copy because the destination is external to Rust.</p>



<a name="232701850"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232701850" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232701850">(Apr 01 2021 at 04:20)</a>:</h4>
<p>Could you say more about this "eternally visible" thing? Because I'm unfamiliar with that.</p>



<a name="232701975"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232701975" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232701975">(Apr 01 2021 at 04:22)</a>:</h4>
<p><a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/215">https://github.com/rust-lang/unsafe-code-guidelines/issues/215</a></p>



<a name="232701977"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232701977" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232701977">(Apr 01 2021 at 04:22)</a>:</h4>
<p>particularly, <em>all</em> MMIO locations are externally visible memory, it would seem, so <em>most</em> MMIO can just use non-volatile access, by that logic (if you're just setting a video mode for example).</p>



<a name="232702027"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232702027" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232702027">(Apr 01 2021 at 04:23)</a>:</h4>
<p>Sure, for MMIO the only part of volatile semantics that you actually need is the guarantee that the access is atomic and not merged/split.</p>



<a name="232702114"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232702114" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232702114">(Apr 01 2021 at 04:24)</a>:</h4>
<p>What I mean by externally visible is that in the abstract machine the GPU itself acts as a separate thread of execution that reads/writes memory. So the compiler cannot elide the memcpy because the destination is then read by another "thread".</p>



<a name="232702159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232702159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232702159">(Apr 01 2021 at 04:25)</a>:</h4>
<p>how does the compiler know that it cannot elide that any more or less than it might think it can elide <code>(0x0400_0000 as *mut u16).write(1234)</code></p>



<a name="232702297"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232702297" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232702297">(Apr 01 2021 at 04:27)</a>:</h4>
<p>particularly, if there are repeated memcopy operations to the same region of memory, can we say <em>for sure</em> that the compiler won't collapse those down into just the final memcopy?</p>



<a name="232702324"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232702324" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232702324">(Apr 01 2021 at 04:27)</a>:</h4>
<p>Side note: for much mmio even the merge-split thing isn't requried</p>



<a name="232702428"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232702428" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232702428">(Apr 01 2021 at 04:29)</a>:</h4>
<p>The compiler is only allowed to elide when it <em>knows</em> that the memory is private. This can be because it is a local variable or because the visibility rules prevent external code from accessing it (think <code>static</code> in C). If the compiler cannot determine this, it <em>must</em> conservatively assume that the memory may be accessed externally.</p>



<a name="232702508"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232702508" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232702508">(Apr 01 2021 at 04:30)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F/near/232702297">said</a>:</p>
<blockquote>
<p>particularly, if there are repeated memcopy operations to the same region of memory, can we say <em>for sure</em> that the compiler won't collapse those down into just the final memcopy?</p>
</blockquote>
<p>Use a fence. This is basically shared memory concurrency where you treat the GPU as a separate thread. You may need to use hardware-specific fences instead of the standard ones in <code>core::sync::atomic</code>, but the same basic principle applies.</p>



<a name="232703167"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232703167" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232703167">(Apr 01 2021 at 04:40)</a>:</h4>
<p>does a standard <code>compier_fence</code> suffice?</p>



<a name="232705550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232705550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232705550">(Apr 01 2021 at 05:15)</a>:</h4>
<p>That's sufficient for the compiler not to elide it. But you generally also need a hardware fence too. Consider a hypothetical case where the CPU has a massive store buffer: a sufficiently smart CPU could elide earlier stores that are overwritten by later stores, which means the GPU only sees the final data, not any intermediate stores.</p>



<a name="232705710"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232705710" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232705710">(Apr 01 2021 at 05:18)</a>:</h4>
<p>Luckily I'm using a CPU designed in 1994 that has no such nonsense.</p>



<a name="232705800"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232705800" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232705800">(Apr 01 2021 at 05:19)</a>:</h4>
<p>As a general rule you need a fence that synchronizes through all layers between you and the target hardware. ARM has an operand to the DMB/DSB instructions which specifies the domain that it applies to: non-shareable, inner-shareable, outer-shareable, system.</p>



<a name="232705805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232705805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232705805">(Apr 01 2021 at 05:19)</a>:</h4>
<p>I was just going to suggest to use assembly if there are special instructions to perform uncached writes to device memory, but I guess that doesn't apply there</p>



<a name="232705898"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232705898" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232705898">(Apr 01 2021 at 05:20)</a>:</h4>
<p>I'm unfamiliar with DMB and DSB. I take it they were added after ARMv4T?</p>



<a name="232706051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232706051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232706051">(Apr 01 2021 at 05:22)</a>:</h4>
<p>Before ARMv7 DMB &amp; DSB are implemented as instruction on CP15. On ARMv7 they became dedicated instructions.</p>



<a name="232706338"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232706338" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232706338">(Apr 01 2021 at 05:28)</a>:</h4>
<p>Actually I just looked it up and it seems that DMB/DSB were introduced in ARMv6.</p>



<a name="232706350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20the%20other%20volatile%20ops%3F/near/232706350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20the.20other.20volatile.20ops.3F.html#232706350">(Apr 01 2021 at 05:28)</a>:</h4>
<p>So in your case you only need a compiler fence for ARMv4.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>